package view;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


import controller.FirewallSession;

/**
 * Class is responsible for logger frame.
 * Frame contains: 	two tables - for FW access/deny logger and global logger of user actions.
 * 					Help, Cancel and Finish buttons.
 * 					Logger mode buttons (static/dynamic).
 * 					Logger operation buttons (filter, reset, logger on/off).
 */
public class LoggerFrame extends JFrame
{
	/**
	 * Serial version ID - for serialization
	 */
	private static final long serialVersionUID = -1938810537384757114L;

	/**
	 * server controller
	 */
	public FirewallSession UI;
	
	/**
	 * Current shown logger frame
	 */
	public static LoggerFrame currentloggerFrame = null;

	/**
	 * FW Logger panel
	 */
	private LoggerPanel logTable = null;
	
	/**
	 * Global Logger panel
	 */
	private LoggerPanel logGlobalTable = null;
	
	/**
	 * Timer for logger dynamic update
	 */
	private static LoggerDynamicAction dynamicLoggerTimer = new LoggerDynamicAction();
	
	/**
	 * Button for turnig logger on/off.
	 */
	public static JButton logonoff = null;

	/**
	 * Button for static logger turn on.
	 */
	private static JButton staticMode = null;
	
	/**
	 * Button for dynamic logger turn on.
	 */
	private static JButton dynamicMode = null;
	
	/**
	 * C'tor - Frame with specified controller is created:
	 * two tables, action buttons and stadart buttons are defined. 
	 * @param ui	- the controller for the system actions
	 */
	private LoggerFrame(FirewallSession UI)
	{	
		super("Logger");
		this.UI = UI;
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setSize(Globals.loggerFrameSize);
		setLayout(new BorderLayout());
		
		addStandartButtons();
		addLoggerButtons();
		addLoggerTable();
		setLocationRelativeTo(null);
	}
	
	/**
	 * Returns current frame if exists, else creates and registers it.
	 * @return logger frame
	 */
	public static LoggerFrame getInctance(FirewallSession ui)
	{
		if(currentloggerFrame == null)
		{
			/* create new logger frame */
			currentloggerFrame = new LoggerFrame(ui);
			/* register logger frame for status bar */
		    StatusBar.register(currentloggerFrame);
		}
		else
		{
			/* rebuild the frame tables */
			LoggerTable.currentLoggerTable.buildTable();
			LoggerGlobalTable.currentLoggerGlobalTable.buildTable();
		}
	    
		/* Disable the current static/dynamic mode button */
		if(Settings.loggerStaticMode)
		{
			staticMode.setEnabled(false);
		}
		else
		{
			dynamicMode.setEnabled(false);
			dynamicLoggerTimer.start();
		}
		
		return currentloggerFrame;
	}
	
	/**
	 * Add logger buttons: mode buttons, adction buttons, standart buttons
	 */
	private void addLoggerButtons() 
	{
		JPanel buttons = new JPanel();
		buttons.setLayout(new GridLayout(1,3));
	    add(buttons, BorderLayout.NORTH);
	    
	    
		/* Buttons for mode set */
		Box modeBox = Box.createVerticalBox();
		
		staticMode = new JButton("Static Mode");
		staticMode.setToolTipText("Logger displays last received data");
		staticMode.setMaximumSize(Globals.buttonSize);

		dynamicMode = new JButton("Dynamic Mode");
		dynamicMode.setToolTipText("Logger dynamically displays new data");
		dynamicMode.setMaximumSize(Globals.buttonSize);
		
		modeBox.add(staticMode);
		modeBox.add(dynamicMode);
		buttons.add(modeBox);
	
		/* Buttons for filter settings and restoring */	
		Box optionsBox = Box.createVerticalBox();
	
		JButton sort = new JButton("Filter");
		sort.setToolTipText("Filter the logger reports by chosen parameter");
		sort.setMaximumSize(Globals.buttonSize);
		JButton reset = new JButton("Reset");
		reset.setToolTipText("Set the default settings");
		reset.setMaximumSize(Globals.buttonSize);
		
		optionsBox.add(sort);
		optionsBox.add(reset);
		
		buttons.add(optionsBox);
		
		/* Button for logger turning on/off */
		try {
			/* Get the current button status */
			if(UI.isLogEnabled())
			{
				StatusBar.loggerOn = true;
				logonoff = new JButton("Logger off");
				logonoff.setToolTipText("Turn off the logger");
			}
			else
			{
				StatusBar.loggerOn = false;
				logonoff = new JButton("Logger on");
				logonoff.setToolTipText("Turn on the logger");			
			}
		} catch (RemoteException e1)
		{
			/* If there is RMI connection problem, assumption the logger is off */
			ErrorFrame.AddError("RMI connection problems: logger status undeclared", this);
			logonoff = new JButton("Logger off");
		}
			
		Box logBox = Box.createVerticalBox();
		logonoff.setMaximumSize(Globals.buttonSize);
		logBox.add(logonoff);
		buttons.add(logBox);
		
		/* Set the default settings */
		reset.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) 
			{
				Settings.historyDepth = Settings.DEFAULT_LOGGER_HISTORY_DEPTH;
				Settings.currentFilterType = FilterType.ALL;
				LoggerTable.currentLoggerTable.buildTable();
				LoggerGlobalTable.currentLoggerGlobalTable.buildTable();
			}	  
		});
		
		/* Set static mode */
		staticMode.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) 
			{
				Settings.loggerStaticMode = true;
				staticMode.setEnabled(false);
				dynamicMode.setEnabled(true);
				
				dynamicLoggerTimer.stop();
			}	  
		});
		
		/* Set dynamic mode */
		dynamicMode.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) 
			{
				Settings.loggerStaticMode = false;
				staticMode.setEnabled(true);
				dynamicMode.setEnabled(false);
				
				dynamicLoggerTimer.start();
			}	  
		});
	
		/* Open filter window by click */
		sort.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) 
			{
				LoggerFilterFrame msg = new LoggerFilterFrame();
				msg.setVisible(true);
			}	  
		});	
		
		/* Turn, logger on/off according to the current status */
		logonoff.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) 
			{
				/* If logger is on - turn off and opposite  */
				if(StatusBar.loggerOn)
				{
					try
					{
						UI.disableLog();
					}
					catch (Exception e)
					{
						ErrorFrame.AddError("Logger can't be turned off", currentloggerFrame);
					} 
				}
				else
				{
					try
					{
						UI.enableLog();
					}
					catch (Exception e)
					{
						ErrorFrame.AddError("Logger can't be turned on", currentloggerFrame);
					}
				}
			}	  
		});
	}
	
	/**
	 * Adds finish and help buttons.
	 * Builds their listeners.
	 */
	private void addStandartButtons() 
	{
		Box tableBox = Box.createHorizontalBox();
		
		JButton finish = new JButton("Finish");
		finish.setToolTipText("Close and save changes");
		JButton help = new JButton("Help");
		help.setToolTipText("Help for logger screen");
		
		tableBox.add(help);		
		tableBox.add(finish);
		
		/*Help button listener - closes the frame*/		
		help.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) 
			{
				HelpFrame.currentHelpFrame.ShowDesc(Globals.LOGGER);		
			}	  
		});	
		
		/* Finish button - stop the logger update time if it's initialized */
		finish.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) 
			{
				LoggerFrame.currentloggerFrame.dispose();				
			}	  
		});

	    add(tableBox, BorderLayout.SOUTH);
	}

	/**
	 * Adds tables for logger data.
	 */
	private void addLoggerTable()
	{
		JPanel tables = new JPanel();
		tables.setLayout(new BorderLayout());
		
		logTable = new LoggerPanel(UI, LoggerTableType.SESSIONS_TABLE);
		tables.add(logTable, BorderLayout.NORTH);
		
		JPanel otherTables = new JPanel();
		otherTables.setLayout(new BorderLayout());
		
		logGlobalTable = new LoggerPanel(UI, LoggerTableType.GLOBAL_TABLE);
		
		otherTables.add(logGlobalTable, BorderLayout.NORTH);
		
		StatisticsPanel statTable = new StatisticsPanel(UI);		
		otherTables.add(statTable, BorderLayout.SOUTH);
		
		
		tables.add(otherTables, BorderLayout.SOUTH);
		add(tables, BorderLayout.CENTER);
	}

	/**
	 * Actions on close operation.
	 */
	public void dispose()
	{
		/* Stop all timers */
		if(dynamicLoggerTimer.timer != null)
		{
			dynamicLoggerTimer.stop();
		}
		
		super.dispose();
	}
}
